home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xhearts / hearts.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  6KB  |  349 lines

  1. /*
  2.  * hearts - human interface to hearts program
  3.  *
  4.  * All smarts are in heartsd, which is invoked by initial caller of hearts.
  5.  *
  6.  * Private messages, last-play, auto-play added by:
  7.  *      Mike Yang of Silicon Graphics (mikey@sgi.com)
  8.  *
  9.  * By Bob Ankeney or Generic Computer Products
  10.  * Bug reports to:
  11.  * ...!tektronix!reed!bob
  12.  *
  13.  *
  14.  * Commands to hearts client (r = rank, s = suit):
  15.  *
  16.  * Ars        Add card to hand.
  17.  * Rrs        Remove card from hand.
  18.  * En        Erase window n.
  19.  * G        Get a card.
  20.  * Pnrs<name>    Play card from player n, whose name is <name>.
  21.  * Snpptt<name>    Score points (pp) and total points (tt) for player n.
  22.  * Mn<text>    Message <text> is placed in window n.
  23.  * X        Go away.
  24.  * Z        Game over, socket closing.
  25.  *
  26.  * Messages from client:
  27.  *
  28.  * Prs        Pass/Play card from hand.
  29.  * M<text>        Send message <text> to all players.
  30.  *
  31.  */
  32.  
  33. #include <sys/errno.h>
  34. #include "misc.h"
  35. #include "defs.h"
  36. #include "local.h"
  37. #include "client.h"
  38. #ifdef SYSV
  39. #include <sys/termio.h>
  40. #endif
  41.  
  42. int    dist_socket, dealer_socket;
  43. char    game_over, first_game;
  44. char    host[256];
  45.  
  46. char    *snames[] = {
  47.         "",
  48.         "clubs",
  49.         "diamonds",
  50.         "hearts",
  51.         "spades"
  52.     },
  53.     rnames[] = " 23456789TJQKA";
  54.  
  55. get_going()
  56. {
  57.     int    dealer_port;
  58.     char    *name, *getenv();
  59.     /*
  60.      * Connect to distributor.  If not available, start it.
  61.      */
  62.     if ((dist_socket = connect_to(host, PORT)) == 0) {
  63.         start_distributor();
  64.         if ((dist_socket = connect_to(host, PORT)) == 0)
  65.             death("Can't invoke distributor!");
  66.     }
  67.     /*
  68.      * Get dealer port and connect to it.
  69.      * If port returned == 0, restart game with old dealer.
  70.      */
  71.     if (dealer_port = select_game()) {
  72.         if (!first_game) {
  73.                 (void) close(dealer_socket);
  74.             close_socket(dealer_socket);
  75.         }
  76.         if ((dealer_socket = connect_to(host, dealer_port)) == 0)
  77.             death("Can't connect to dealer!\n");
  78.         if ((name = getenv("HEARTS")) == NULL)    /* get user name */
  79.             if ((name = getenv("NAME")) == NULL)
  80.                 name = getenv("USER");
  81.         init_socket();
  82.         write_socket(dealer_socket, name);    /* tell dealer */
  83.     }
  84.     start_game();
  85. }
  86.  
  87. do_command(buf)
  88. char    *buf;
  89. {
  90.     char    rch, sch;
  91.     int    player, suit, pts, total_pts, window_num;
  92.  
  93.     switch (buf[0]) {
  94.     case 'A' :        /* Add card to hand */
  95.             enter_card(get_rank(buf[1]), get_suit(buf[2]));
  96.         break;
  97.  
  98.     case 'R' :        /* Remove card from hand */
  99.             remove_card(get_rank(buf[1]), get_suit(buf[2]));
  100.         break;
  101.  
  102.     case 'E' :        /* Erase window */
  103.             erase_window(buf[1] - '0');
  104.         break;
  105.  
  106.     case 'G' :        /* Get card */
  107.         read_card();
  108.         break;
  109.  
  110.     case 'P' :        /* Play card from player */
  111.         (void) sscanf(buf+1, "%1d %c %c", &player, &rch, &sch);
  112.         play_card(player, rch, sch, buf+4);
  113.         break;
  114.  
  115.     case 'S' :        /* Score points for player */
  116.         (void) sscanf(buf+1, "%1d %3d %3d", &player, &pts, &total_pts);
  117.         score_points(player, pts, total_pts, buf+8);
  118.         break;
  119.  
  120.     case 'M' :        /* Print message in window */
  121.             display_message(buf[1] - '0', buf+2);
  122.         break;
  123.  
  124.     case 'X' :        /* Game over */
  125.             game_is_over();
  126.         game_over = TRUE;
  127.         first_game = FALSE;
  128.         break;
  129.  
  130.     case 'Z' :        /* Game over, socket closing */
  131.             game_is_over();
  132.         game_over = TRUE;
  133.             first_game = TRUE;
  134.         (void) close(dealer_socket);
  135.         close_socket(dealer_socket);
  136.     }
  137. }
  138.  
  139. /*
  140.  * Filter out nasties from message in buffer
  141.  */
  142.  
  143. mikey_strcmp(s,t)
  144. char s[], t[];
  145. {
  146.   int i;
  147.  
  148.   i = 0;
  149.   while ((s[i] == t[i]) || (s[i] >= 'A' && s[i] <= 'Z' &&
  150.                 (s[i] - 'A' + 'a') == t[i]))
  151.     if (t[i++] == '\0')
  152.       return(TRUE);
  153.   return((t[i] == '\0'));
  154. }
  155.  
  156. block(buf, what)
  157. char *buf, *what;
  158. {
  159.   int i;
  160.  
  161.   for (i=0;i<=strlen(what);i++)
  162.     *buf++ = *what++;
  163. }
  164.  
  165. mikey_filter(buf)
  166. char *buf;
  167. {
  168.   int i;
  169.  
  170.   for (i=1;i<strlen(buf);i++) {
  171.     if (mikey_strcmp(buf+i,"asshole"))
  172.       block(buf+i,"a--hole");
  173.     if (mikey_strcmp(buf+i,"tit"))
  174.       block(buf+i,"t-t");
  175.     if (mikey_strcmp(buf+i,"shit"))
  176.       block(buf+i,"s--t");
  177.     if (mikey_strcmp(buf+i,"damn"))
  178.       block(buf+i,"d--n");
  179.     if (mikey_strcmp(buf+i,"fuck"))
  180.       block(buf+i,"f--k");
  181.   }
  182. }
  183.  
  184. /**********************************************************************/
  185.  
  186. do_socket()
  187. {
  188.   char buf[64];
  189.  
  190.   if (!read_socket(dealer_socket, buf))
  191.     death("Dealer died!!");
  192.   do_command(buf);
  193. }
  194.  
  195. send_message(msg)
  196. char *msg;
  197. {
  198.   char buf[64];
  199.  
  200.   strcpy(buf, "M");
  201.   if (strlen(msg) <= 62) {
  202.     strcat(buf, msg);
  203.   } else {
  204.     strncat(buf, msg, 62);
  205.   }
  206.   mikey_filter(buf);
  207.   write_socket(dealer_socket, buf);
  208. }
  209.  
  210. send_private_message(who, msg)
  211. int who;
  212. char *msg;
  213. {
  214.   char buf[64];
  215.  
  216.   sprintf(buf, ";%d", who);
  217.   if (strlen(msg) <= 61) {
  218.     strcat(buf, msg);
  219.   } else {
  220.     strncat(buf, msg, 61);
  221.   }
  222.   mikey_filter(buf);
  223.   write_socket(dealer_socket, buf);
  224. }
  225.  
  226. toggle_private_messages()
  227. {
  228.   char buf[2];
  229.  
  230.   buf[0] = '~';
  231.   buf[1] = '\0';
  232.   write_socket(dealer_socket, buf);
  233. }
  234.  
  235. send_card(rank, suit)
  236. int rank, suit;
  237. {
  238.   char buf[64];
  239.  
  240.   sprintf(buf, "P%c%c", rank, suit);
  241.   write_socket(dealer_socket, buf);
  242. }
  243.  
  244. send_auto()
  245. {
  246.   char buf[64];
  247.  
  248.   sprintf(buf, "P?%c", HEARTS);
  249.   write_socket(dealer_socket, buf);
  250. }
  251.  
  252. close_windows()
  253. {
  254.     (void) signal(SIGINT, SIG_IGN);
  255.     terminate();
  256. }
  257.  
  258. death(buf)
  259. char    *buf;
  260. {
  261.     close_windows();
  262.     printf("%s\n", buf);
  263.     exit(1);
  264. }
  265.  
  266. wimp_out()
  267. {
  268.     close_windows();
  269.     exit(0);
  270. }
  271.  
  272. get_rank(rch)
  273. int rch;
  274. {
  275.     int    i;
  276.  
  277.     for (i = 1; i <= MAX_RANK; i++)
  278.         if (rch == rnames[i])
  279.             return(i);
  280.     return(0);
  281. }
  282.  
  283. get_suit(sch)
  284. int sch;
  285. {
  286.     int    i;
  287.  
  288.     for (i = 1; i <= MAX_SUIT; i++)
  289.         if (sch == *snames[i])
  290.             return(i);
  291.     return(0);
  292. }
  293.  
  294. start_new_game()
  295. {
  296.   write_socket(dist_socket, "n");
  297. }
  298.  
  299. join_game(i)
  300. int i;
  301. {
  302.   char buf[64];
  303.  
  304.   (void) sprintf(buf, "j%d", i);
  305.   write_socket(dist_socket, buf);
  306. }
  307.  
  308. do_dist()
  309. {
  310.   int i;
  311.   char buf[64];
  312.  
  313.   if (read_socket(dist_socket, buf) == 0)
  314.     dist_died(3);
  315.   i = update_table(buf);
  316.   show_tables(cur_screen_table);
  317. }
  318.  
  319. main(argc, argv)
  320. int    argc;
  321. char    **argv;
  322. {
  323. /* Call init first, in case the client wants to parse arguments */
  324.     init(&argc, argv);
  325.  
  326.     if (argc > 2) {
  327.         fprintf(stderr, "usage: %s [hostname]\n", *argv);
  328.         exit(1);
  329.     }
  330.     if (argc == 2)
  331.         (void) strcpy (host, *++argv);
  332.     else
  333.         (void) gethostname(host, sizeof(host));    /* host is this machine */
  334.  
  335.     first_game = TRUE;
  336.  
  337.     (void) signal(SIGINT, wimp_out);
  338.  
  339.     for (;;) {
  340.         game_over = FALSE;
  341.         get_going();
  342.         do {
  343.             scan();
  344.         }
  345.         while (!game_over);
  346.     }
  347. }
  348.  
  349.